package com.example.administrator.basedemos.activity;

import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.example.administrator.basedemos.R;
import com.example.administrator.basedemos.adapter.MainAdapter;
import com.example.administrator.basedemos.api.GitHubAPi;
import com.example.administrator.basedemos.base.BaseActivity;
import com.example.administrator.basedemos.bean.GithubUserBean;
import com.example.administrator.basedemos.bean.UserBean;
import com.example.administrator.basedemos.utils.LogUtil;
import com.example.administrator.basedemos.utils.TmtUtils;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 创建者     ZCL
 * 创建时间   2018/3/12 17:37
 * 描述	      ${TODO}
 * <p>
 * 更新者     $Author$
 * 更新时间   $Date$
 * 更新描述   ${TODO}
 */

public class Rxjava2_1Activity extends BaseActivity {
    private static final String TAG = "Rxjava2Activity";
    @BindView(R.id.recyclerview_weight)
    RecyclerView mRecyclerviewWeight;
    @BindView(R.id.search_edt)
    EditText     mSearchEdt;
    @BindView(R.id.trottle_frist_btn)
    Button       mTrottleFristBtn;
    @BindView(R.id.timer_btn)
    Button       mTimeBtn;
    private MainAdapter mAdapter;
    private Observable  mObservable;
    private Observer    mObserver;
    private Consumer    mConsumer;
    private String BaseUrl = "https://api.github.com/";
    private GitHubAPi mAPiService;

    //https://api.github.com/users/1
    @Override
    public void initView() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BaseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                //.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        mAPiService = retrofit.create(GitHubAPi.class);
    }


    @Override
    public void initData() {
        mTrottleFristBtn.setTextColor(ContextCompat.getColor(this, R.color.green));
        mTrottleFristBtn.setText(getString(R.string.throttle));
        mTrottleFristBtn.setBackgroundResource(R.color.red);

        setTimerBtn();

        ArrayList<String> list = new ArrayList<>();

        list.add( "flatmap");
        list.add( "搜索框debounce");
        list.add( "连续点击throttleFirst(1000, TimeUnit.MILLISECONDS)");
        list.add( "合并本地缓存与网络数据");
        list.add( "倒计时");


        mRecyclerviewWeight.setLayoutManager(new GridLayoutManager(this, 2));
        mAdapter = new MainAdapter(R.layout.main_item, list);

        mRecyclerviewWeight.setAdapter(mAdapter);

        mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                switch (position) {
                    case 0:
                        flatMap();
                        break;
                    case 3:
                        margeObserverable();
                        break;
                }
            }
        });
    }

    /**
     * 合并网络与本地数据
     */
    private void margeObserverable() {
        Observable.merge(getLocalData(), getNetworkData())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ArrayList<String>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(ArrayList<String> strings) {
                        for (String s:strings) {
                        LogUtil.util(TAG,"返回数据是:"+ s);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        LogUtil.util(TAG,"onError");
                    }

                    @Override
                    public void onComplete() {
                        LogUtil.util(TAG,"onComplete");
                    }
                });
    }

    /**
     * 发送本地数据
     * @return
     */
    public Observable<ArrayList<String>> getLocalData() {

       // return Observable.just(new UserBean("",""));
        ArrayList<String> list = new ArrayList<>();
        list.add("本地1");
        list.add("本地2");
        return Observable.just(list);
    }

    /**
     * 请求网络数据
     * @return
     */
    private Observable<ArrayList<String>> getNetworkData() {

        //return mAPiService.rxToken("").subscribeOn(Schedulers.io());
        ArrayList<String> list = new ArrayList<>();
        list.add("网络1");
        list.add("网络2");
        return Observable.just(list).subscribeOn(Schedulers.io());
    }


    @Override
    public void initListener() {
        super.initListener();
        long lastTime = 0;

        long currentTimeMillis = System.currentTimeMillis();
        if (lastTime - currentTimeMillis > 500) {
            //间隔草果500秒可以执行  否则不执行
        }
        lastTime = currentTimeMillis;

        RxView.clicks(mTrottleFristBtn).
                throttleFirst(1000, TimeUnit.MILLISECONDS)
                .subscribe(new Observer<Object>() {
                               @Override
                               public void onSubscribe(Disposable d) {

                               }

                               @Override
                               public void onNext(Object o) {
                                   mTimeBtn.setBackgroundColor(ContextCompat.getColor(Rxjava2_1Activity.this,R.color.red));
                                   mTimeBtn.setTextColor(ContextCompat.getColor(Rxjava2_1Activity.this,R.color.white));
                                   LogUtil.util(TAG, "连续点击" + System.currentTimeMillis());
                                   TmtUtils.midToast(Rxjava2_1Activity.this, "连续点击!" + System.currentTimeMillis());

                               }

                               @Override
                               public void onError(Throwable e) {

                               }

                               @Override
                               public void onComplete() {

                               }
                           }
                );

        RxTextView.textChanges(this.mSearchEdt)//监听textview变化必须在ui线程
                .debounce(500, TimeUnit.MILLISECONDS)//每500毫秒请求一次
                .filter(new Predicate<CharSequence>() {
                    @Override
                    public boolean test(CharSequence charSequence) throws Exception {
                        return charSequence.toString().trim().length() > 0;
                    }
                })
                .flatMap(new Function<CharSequence, ObservableSource<ArrayList<String>>>() {
                    @Override
                    public ObservableSource<ArrayList<String>> apply(CharSequence charSequence) throws Exception {
                        //通过网络请求得到数据并发送  假数据  但是使用fltmap会每次都返回数据
                        ArrayList<String> list = new ArrayList<>();
                        list.add("长");
                        list.add("段");
                        //如果使用rx+retrofit 直接返回
                        LogUtil.util(TAG, "返回数据是:" + list.toString());
                        return Observable.just(list);
                    }
                }).subscribeOn(Schedulers.io())
                /**
                 * 一定记得更新ui是observeOn 不是subscribeOn
                 * “subscribeOn()”这个方法是设定Observable所在线程
                 */
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<ArrayList<String>>() {
                    @Override

                    public void accept(final ArrayList<String> strings) throws Exception {
                        //todo 更新搜索成功ui
                        TmtUtils.midToast(Rxjava2_1Activity.this, "搜索成功!" + strings.toString());
                    }
                });
    }

    private void flatMap() {
        Observable.just(getParams()).flatMap(new Function<UserBean, ObservableSource<GithubUserBean>>() {
            @Override
            public ObservableSource<GithubUserBean> apply(UserBean userBean) throws Exception {
                ///通过上传parmabean得到GitHubBean 并在此返回一个可发射的observaerable 将GithubUserBean发送出去
                //GithubUserBean githubUserBean = mAPiService.login(userBean).execute().body(); -->retrofit 方式
                //将github作为下次请求参数发送出去
                //return Observable.just(githubUserBean);
                //rx+retrofit 方式
                return mAPiService.rxLogin(userBean);

            }

        })
                /**
                 * switchMap 于faltmap用法完全一致 但是flatmap每次请求都会返回一次数据每次数据
                 * 返回的顺序并不是一致的  而且并不是每次关键词都是有用的 只有最终的才是用户想要的
                 * switchmap 就是将这些obserable发送的数据集合转换为observerables集合 然后只发送
                 * observerables最近的一次数据
                 */
                .switchMap(new Function<GithubUserBean, ObservableSource<UserBean>>() {
                    @Override
                    public ObservableSource<UserBean> apply(GithubUserBean githubUserBean) throws Exception {
                        //假设通过token获取更多个人信息
                        // UserBean userBean = mAPiService.Token(githubUserBean.getName()).execute().body();
                        //return Observable.just(userBean);  -->retrofit 方式

                        //rx+retrofit 方式
                        return mAPiService.rxToken(githubUserBean.token);
                    }
                })//.flatMap(new Function<GithubUserBean, ObservableSource<UserBean>>() {
                //  @Override
                //  public ObservableSource<UserBean> apply(GithubUserBean githubUserBean) throws Exception {
                //      return mAPiService.rxToken(githubUserBean.token);
                //  }
                //})
                .subscribeOn(Schedulers.io())//无上限线程池 重复使用
                .observeOn(AndroidSchedulers.mainThread())//更新界面切换回主线程
                .subscribe(new Consumer<UserBean>() {
                    @Override
                    public void accept(UserBean userBean) throws Exception {
                        TmtUtils.midToast(Rxjava2_1Activity.this, "更新UI!");
                    }
                });
    }

    /**
     * UserBean 账号密码封装进去一次来登陆
     */
    private UserBean getParams() {
        return new UserBean("zhang", "zcl");
    }

     @OnClick({R.id.timer_btn})
         public void OnClik(View v){
             switch (v.getId()) {
                         case R.id.timer_btn:
                             final int count = 10;
                             //不延迟从0开始
                                Observable.interval(0,1000,TimeUnit.MILLISECONDS)
                                        .take(count +1)//执行10次
                                            .map(new Function<Long, Long>() {
                                                //对Observable发射的数据都应用一个函数，然后再发射最后的结果集。最后map()方法返回一个新的Observable。
                                                //如把[“this”,”is”,”rxJava”]转成[“RXJAVA”,”IS”,“THIS”]。
                                                @Override
                                                public Long apply(Long aLong) throws Exception {
                                                    return count -aLong;
                                                }
                                            })
                                        .doOnSubscribe(new Consumer<Disposable>() {
                                            @Override
                                            public void accept(Disposable disposable) throws Exception {
                                                mTimeBtn.setClickable(false);//在执行结束前不能点击
                                                mTimeBtn.setTextColor(ContextCompat.getColor(Rxjava2_1Activity.this,R.color.white));
                                                mTimeBtn.setBackgroundColor(ContextCompat.getColor(Rxjava2_1Activity.this,R.color.red));
                                            }
                                        })
                                        .observeOn(AndroidSchedulers.mainThread())
                             .subscribe(new Observer<Long>() {
                                 @Override
                                 public void onSubscribe(Disposable d) {

                                 }

                                 @Override
                                 public void onNext(Long aLong) {
                                     LogUtil.util(TAG,"倒计时num:"+aLong);
                                     mTimeBtn.setText("剩余"+aLong+"s");
                                 }

                                 @Override
                                 public void onError(Throwable e) {
                                     setTimerBtn();
                                 }

                                 @Override
                                 public void onComplete() {
                                     setTimerBtn();
                                 }
                             });

                             break;
                         default:
                             break;
                     }
         }

    private void setTimerBtn() {
        mTimeBtn.setTextColor(ContextCompat.getColor(Rxjava2_1Activity.this, R.color.red));
        mTimeBtn.setBackgroundResource(R.color.gray_b);
        mTimeBtn.setClickable(true);
        mTimeBtn.setText(getString(R.string.timer_btn));
    }

    @Override
    public int setLayoutId() {
        return R.layout.activity_rxjava;
    }

}
